package com.study.excel;

import com.study.dto.UserNew;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.QuoteMode;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

@RestController
@RequestMapping("/file")
public class FileController {
    private final String CSV_MEDIA_TYPE = "application/csv;charset=UTF-8";
    public static byte[] UTF8_BOM = { (byte) 0xef, (byte) 0xbb, (byte) 0xbf };
    private static List<String> csvHeader = Arrays.asList(
            "用户ID", "用户名", "邮箱", "手机号", "姓","版本号"
    );

    @GetMapping("/download")
    public ResponseEntity<Resource> downloadSegmentProfile() throws Exception {
        UserNew user = new UserNew();
        user.setId("23da23412");
        user.setUsername("shangz");
        user.setEmail("324213@qq.com");
        user.setPhone("18347673284");
        UserNew user1 = new UserNew();
        user1.setId("43297hfsahf");
        user1.setUsername("lisi");
        user1.setEmail("032848234@qq.com");
        user1.setPhone("176342343");
        List<UserNew> users = Arrays.asList(user, user1);

        InputStreamResource file = buildCSVFile(users);

        String disposition = String.format("attachment; filename=SegmentProfile_test.csv");
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, disposition)
                .contentType(MediaType.parseMediaType(CSV_MEDIA_TYPE))
                .body(file);
    }

    /**
     * 使用泛型支持任何对象
     * @param body
     * @param <T>
     * @return
     * @throws Exception
     */
    private <T> InputStreamResource buildCSVFile(List<T> body) throws Exception {
        final CSVFormat format = CSVFormat.DEFAULT.withQuoteMode(QuoteMode.MINIMAL);

        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            out.write(UTF8_BOM);
            CSVPrinter csvPrinter = new CSVPrinter(new PrintWriter(out), format);

            //表头
            csvPrinter.printRecord(csvHeader);
            for (T t : body) {
                /*Class<? extends Object> clazz = t.getClass();
                T t1 = (T) clazz.newInstance();*/
                Field[] declaredFields = t.getClass().getDeclaredFields();
                List<String> csvLine = new LinkedList<>();
                T finalT = t;
                Arrays.stream(declaredFields).forEach(field -> {
                    field.setAccessible(true);
                    try {
                        csvLine.add(String.valueOf(field.get(finalT)));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                });
                //内容填充
                csvPrinter.printRecord(csvLine);
            }

            csvPrinter.flush();
            ByteArrayInputStream is = new ByteArrayInputStream(out.toByteArray());
            InputStreamResource file = new InputStreamResource(is);
            return file;
        } catch (Exception e) {
            throw new Exception("Fail to import segment profile data to CSV file: " + e.getMessage());
        }

    }


}
